import { createStore, Commit } from 'vuex'
import {
  fetchColumns,
  fetchColumn,
  fetchPosts,
  reqLogin,
  getUser,
  reqRegister,
  reqCreatePost
} from '../api/index'
import { objToArr, arrToObj } from '../helper'
import axios, { AxiosRequestConfig } from 'axios'
import { setToken, getToken, removeToken } from '@/utils/token'
export interface Resptype<P = unknown> {
  code: number
  msg: string
  data: P
}
export interface ImageProps {
  _id?: string
  url?: string
  createdAt?: string
  fitUrl?: string
}
export interface ColumnProps {
  _id: string
  title: string
  avatar?: ImageProps
  description: string
}
export interface UserProps {
  isLogin: boolean
  nickName?: string
  _id?: string
  column?: string
  email?: string
  avatar?: ImageProps
  description?: string
}
export interface PostProps {
  _id?: string
  title: string
  excerpt?: string
  content?: string
  image?: ImageProps | string
  createdAt?: string
  column: string
  author?: string | UserProps
  isHTML?: boolean
}
export interface GlobalErrProps {
  status: boolean
  message?: string
}
interface ListProps<P> {
  [id: string]: P
}
export interface GlobalPostsProps {
  data: ListProps<PostProps>
  loadedColumns: ListProps<{ total?: number; currentPage?: number }>
}
export interface GlobalColumnsProps {
  data: ListProps<ColumnProps>
  currentPage: number
  total?: number
}

export interface GlobalDataProps {
  error: GlobalErrProps
  columns: GlobalColumnsProps
  posts: GlobalPostsProps
  user: UserProps
  isloading: boolean
  token: string
}
const asyncAndCommit = async (
  url: string,
  mutationName: string,
  commit: Commit,
  config: AxiosRequestConfig = { method: 'get' },
  extraData?: any
) => {
  const { data } = await axios(url, config)
  if (extraData) {
    commit(mutationName, { data, extraData })
  } else {
    commit(mutationName, data)
  }
  return data
}

const store = createStore<GlobalDataProps>({
  state: {
    error: {
      status: false
    },
    token: getToken(),
    isloading: false,
    columns: { data: {}, currentPage: 0 },
    posts: { data: {}, loadedColumns: {} },
    user: { isLogin: false }
  },

  mutations: {
    SETERROR(state, e: GlobalErrProps) {
      state.error = e
    },
    createPost(state, newPost) {
      state.posts.data[newPost._id] = newPost
    },
    fetchColumns(state, rawData) {
      const { data } = state.columns
      const { list, count, currentPage } = rawData.data
      state.columns = {
        data: { ...data, ...arrToObj(list) },
        total: count,
        currentPage: currentPage * 1
      }
    },
    FETCHCOLUMN(state, rawData) {
      state.columns.data[rawData.data._id] = rawData.data
    },
    FETCHPOSTS(state, postdata) {
      state.posts = postdata.list
    },
    SETLOADING(state, status) {
      state.isloading = status
    },
    SETTOKEN(state, token) {
      state.token = token
      setToken(token)
      axios.defaults.headers.common.Authorization = `Bearer ${token}`
    },
    USERINFO(state, rawdata) {
      console.log(rawdata.data)

      state.user = { isLogin: true, ...rawdata.data }
    },
    LOGOUT(state) {
      state.token = ''
      removeToken()
      state.user = { isLogin: false }

      delete axios.defaults.headers.common.Authorization
    }
  },
  actions: {
    async Register({ commit }, payload) {
      const result = await reqRegister(payload)
      console.log(result)
      return 'ok'
    },
    async Login({ commit }, params) {
      // eslint-disable-next-line prefer-const
      let result = await reqLogin(params)
      console.log(result)
      const { token } = result.data
      commit('SETTOKEN', token)
      axios.defaults.headers.common.Authorization = `Bearer ${token}`
      return 'ok'

      // return asyncAndCommit('user/login', 'login', commit, params)
    },
    async getUserInfo({ commit }) {
      const result = await getUser()

      commit('USERINFO', result)
      return 'ok'
    },
    fetchCurrentUser({ commit }) {
      return asyncAndCommit('/user/current', 'USERINFO', commit)
    },
    async LoginAndFetch({ dispatch }, loginData) {
      await dispatch('Login', loginData)
      return await dispatch('fetchCurrentUser')
    },
    createPost({ commit }, payload) {
      return asyncAndCommit('/posts', 'createPost', commit, {
        method: 'post',
        data: payload
      })
    },

    // async createPost({ commit }, payload) {
    //   const result = await reqCreatePost(payload)
    //   console.log(result)
    //   commit('createPost', result.data)
    //   if (result.data) {
    //     return 'ok'
    //   }
    // },
    // async fetchColumns({ commit }) {
    //   // fetchColumns().then((res) => {
    //   //   console.log(res.data)
    //   //   commit('FETCHCOLUMNS', res.data)
    //   // })

    //   const { data } = await fetchColumns()
    //   commit('FETCHCOLUMNS', data)
    // },
    fetchColumns({ state, commit }, params = {}) {
      const { currentPage = 1, pageSize = 6 } = params
      if (state.columns.currentPage < currentPage) {
        return asyncAndCommit(
          `/columns?currentPage=${currentPage}&pageSize=${pageSize}`,
          'fetchColumns',
          commit
        )
      }
    },
    fetchColumn({ commit }, cid) {
      fetchColumn(cid).then((res) => {
        console.log(res.data)
        commit('FETCHCOLUMN', res.data)
      })
    },
    fetchPosts({ commit }, cid) {
      fetchPosts(cid).then((res) => {
        console.log(res.data)
        commit('FETCHPOSTS', res.data)
      })
    }
  },
  getters: {
    // 对象
    // getColumnById: (state) => (id: string) => {
    //   return state.columns.find((c) => c._id === id)
    // },
    getColumnById: (state) => (id: string) => {
      return state.columns.data[id]
    },
    // getPostsByCid: (state) => (cid: string) => {
    //   return state.posts.filter((v) => v.column === cid)
    // },
    getPostsByCid: (state) => (cid: string) => {
      return objToArr(state.posts.data).filter((post) => post.column === cid)
    },
    getCurrentPost: (state) => (id: string) => {
      return state.posts.data[id]
    }
  }
})

export default store
